extends CharacterBody2D
class_name BasicEnemy

## 基础敌人属性
@export var max_health: int = 5
@export var attack_damage: int = 2
@export var move_speed: float = 50.0
@export var detection_range: float = 9999.0  # 全图追踪
@export var attack_cooldown: float = 1.0
@export var attack_range: float = 40.0

## 私有变量
var current_health: int
var player: Node2D = null
var start_position: Vector2
var patrol_target: Vector2
var is_chasing: bool = false
var last_attack_time: float = 0.0
var actual_move_speed: float  # 实际移动速度（包含随机波动）

# 菱形外形（长/短对角线长度）
@export var diamond_long: float = 36.0: set = _set_diamond_long
@export var diamond_short: float = 24.0: set = _set_diamond_short
@export var size_scale: float = 0.6 # 统一缩放，默认约60%
@export var turning_radius: float = 50.0 # 转向半径（像素）
var head_direction: Vector2 = Vector2.UP

# 可视外形：生成菱形精灵
@export var sprite_color: Color = Color(1, 0.25, 0.25, 1.0)

# 掉落（魂石）
@export var soul_stone_drop_rate: float = 0.8 # 80%

# 调试描边（最简单方式）
@export var debug_draw_hitbox: bool = true
@export var debug_color: Color = Color(0.2, 0.6, 1.0, 0.95) # 蓝色
@export var debug_line_width: float = 2.0

# 碰撞体完全由菱形参数驱动（不再从旧 Sprite2D 同步）

func _ready():
	# 初始化血量
	current_health = max_health
	
	# 计算实际移动速度（基础速度 ± 10% 随机波动）
	var speed_variation = randf_range(-0.1, 0.1)  # -10% 到 +10%
	actual_move_speed = move_speed * (1.0 + speed_variation)
	print("敌人生成 - 基础速度: ", move_speed, " 实际速度: ", actual_move_speed)
	
	start_position = global_position
	set_new_patrol_target()
	
	# 查找玩家
	player = get_tree().get_first_node_in_group("player")

	# 将本敌人加入 "enemy" 组，方便调试描边与命中逻辑统一处理
	if not is_in_group("enemy"):
		add_to_group("enemy")
	# 将敌人的碰撞层设置为第2层，匹配子弹的碰撞掩码=2（bullet.tscn）
	collision_layer = 2
	# 敌人不与玩家发生物理碰撞（避免贴身卡住）；Area2D（子弹/感知）仍可检测到
	collision_mask = 0

	# 将碰撞体与可视多边形统一重建（同一套点）
	_rebuild_diamond()
	# 移除任何遗留的旧可视节点（方形 Sprite/ColorRect 等）
	_remove_legacy_visuals(self)

func _physics_process(delta):
	if player:
		var distance_to_player = global_position.distance_to(player.global_position)
		
		if distance_to_player <= detection_range:
			# 追击玩家 - 一直移动，不停止
			is_chasing = true
			# 头朝向玩家：将菱形的长对角线朝向目标，受转向半径限制
			var dir := (player.global_position - global_position).normalized()
			var target_angle := dir.angle() + PI * 0.5
			_rotation_steer_towards(target_angle, delta)
			head_direction = Vector2.UP.rotated(rotation)
			# 移动仅沿头部朝向前进
			move_forward()
			
			# 检查是否可以攻击玩家（直接碰撞检测）
			if distance_to_player <= 20 and can_attack_player():  # 20像素内算碰撞
				attack_player()
		else:
			# 巡逻
			is_chasing = false
			handle_patrol(delta)
	else:
		# 没有玩家时巡逻
		handle_patrol(delta)

	# 调试：持续重绘描边
	if debug_draw_hitbox:
		queue_redraw()

func handle_patrol(delta):
	if global_position.distance_to(patrol_target) < 20:
		set_new_patrol_target()
	else:
		var dir := (patrol_target - global_position).normalized()
		var target_angle := dir.angle() + PI * 0.5
		_rotation_steer_towards(target_angle, delta)
		head_direction = Vector2.UP.rotated(rotation)
		move_forward()

func move_towards(target: Vector2):
	var direction = (target - global_position).normalized()
	velocity = direction * actual_move_speed  # 使用实际移动速度
	move_and_slide()

func move_forward():
	velocity = head_direction * actual_move_speed
	move_and_slide()

func set_new_patrol_target():
	var random_angle = randf() * TAU
	patrol_target = start_position + Vector2(
		cos(random_angle) * 100,
		sin(random_angle) * 100
	)

func take_damage(damage: int):
	current_health -= damage
	current_health = max(0, current_health)
	print("基础敌人受到伤害: ", damage, " 当前血量: ", current_health)
	
	# 如果血量耗尽，死亡
	if current_health <= 0:
		die()

func die():
	print("基础敌人死亡！")
	# 掉落魂石
	_try_drop_soul_stone()
	# 播放死亡动画或效果
	queue_free()  # 从场景中移除敌人

func _try_drop_soul_stone() -> void:
	if randf() <= soul_stone_drop_rate:
		var stone := SoulStone.new()
		get_tree().current_scene.add_child(stone)
		stone.global_position = global_position

func can_attack_player() -> bool:
	var current_time = Time.get_ticks_msec()
	return current_time >= last_attack_time + attack_cooldown * 1000

func attack_player():
	if player and player.has_method("take_damage"):
		player.take_damage(attack_damage)
		last_attack_time = Time.get_ticks_msec()
		print("基础敌人攻击玩家，造成伤害: ", attack_damage)
	else:
		print("基础敌人无法攻击玩家")

## 获取敌人当前速度（用于预判）
func get_enemy_velocity() -> Vector2:
	return velocity

#
# 调试绘制：用最简单方式描边当前敌人的 CollisionShape2D
#
func _draw() -> void:
	if not debug_draw_hitbox:
		return
	var cs := _find_collision_shape(self)
	if not cs or not cs.shape:
		return
	var t: Transform2D = cs.transform
	var shape := cs.shape
	if shape is CircleShape2D:
		var r := (shape as CircleShape2D).radius
		var center := t.origin
		draw_arc(center, r, 0.0, TAU, 48, debug_color, debug_line_width)
	elif shape is RectangleShape2D:
		var half := (shape as RectangleShape2D).size * 0.5
		var corners := [Vector2(-half.x, -half.y), Vector2(half.x, -half.y), Vector2(half.x, half.y), Vector2(-half.x, half.y)]
		var pts: PackedVector2Array = []
		for c in corners:
			pts.append(t * c)
		for i in range(4):
			draw_line(pts[i], pts[(i + 1) % 4], debug_color, debug_line_width)
	elif shape is ConvexPolygonShape2D:
		var poly := shape as ConvexPolygonShape2D
		var pts2: PackedVector2Array = []
		for p in poly.points:
			pts2.append(t * p)
		for i in range(pts2.size()):
			draw_line(pts2[i], pts2[(i + 1) % pts2.size()], debug_color, debug_line_width)

func _find_collision_shape(n: Node) -> CollisionShape2D:
	for child in n.get_children():
		if child is CollisionShape2D:
			return child as CollisionShape2D
		var found := _find_collision_shape(child)
		if found:
			return found
	return null

#
# 统一重建：以 diamond_long/diamond_short 为唯一权威数据
#

func _rebuild_diamond() -> void:
	var points := _setup_diamond_collision()
	_update_body_polygon(points)
	# 确保初始朝向一致
	head_direction = Vector2.UP.rotated(rotation)
	var poly := _ensure_body_polygon()
	if poly:
		poly.rotation = 0.0

func _set_diamond_long(v: float) -> void:
	diamond_long = max(2.0, v)
	_rebuild_diamond()

func _set_diamond_short(v: float) -> void:
	diamond_short = max(2.0, v)
	_rebuild_diamond()

# 创建/更新菱形碰撞体（长对角线 diamond_long，短对角线 diamond_short）

func _setup_diamond_collision() -> PackedVector2Array:
	var cs := _find_collision_shape(self)
	if not cs:
		return PackedVector2Array()
	var shape: Shape2D = cs.shape
	if not (shape is ConvexPolygonShape2D):
		shape = ConvexPolygonShape2D.new()
		cs.shape = shape
	var half_long := diamond_long * size_scale * 0.5
	var half_short := diamond_short * size_scale * 0.5
	var points: PackedVector2Array = [
		Vector2(0, -half_long),
		Vector2(half_short, 0),
		Vector2(0, half_long),
		Vector2(-half_short, 0),
	]
	(shape as ConvexPolygonShape2D).points = points
	return points

# 将碰撞体尺寸匹配到第一个 Sprite2D 的显示尺寸
## 已弃用：旧 Sprite2D 相关逻辑已移除

# 确保存在 BodyPolygon 节点（Polygon2D），用于可视显示，与物理体共用点集
func _ensure_body_polygon() -> Polygon2D:
	var node := get_node_or_null("BodyPolygon")
	if node and node is Polygon2D:
		return node
	var poly := Polygon2D.new()
	poly.name = "BodyPolygon"
	add_child(poly)
	poly.z_index = 0
	return poly

# 用点集更新可视多边形，使其与物理体严格一致
func _update_body_polygon(points: PackedVector2Array) -> void:
	var poly := _ensure_body_polygon()
	if not poly:
		return
	poly.polygon = points
	poly.color = sprite_color
	poly.visible = true

# 递归移除遗留方形可视节点
func _remove_legacy_visuals(n: Node) -> void:
	for child in n.get_children():
		if child is Polygon2D:
			continue
		if child is Sprite2D or child is ColorRect:
			child.queue_free()
			continue
		_remove_legacy_visuals(child)

# 基于转向半径的渐进旋转
func _rotation_steer_towards(target_angle: float, delta: float) -> void:
	# 角速度上限：omega = v / R
	var max_omega: float = 0.0
	if turning_radius > 1.0:
		max_omega = abs(actual_move_speed) / turning_radius
	# 归一化角度差到 [-PI, PI]
	var diff: float = fmod((target_angle - rotation + PI), TAU) - PI
	var step: float = clamp(diff, -max_omega * delta, max_omega * delta)
	rotation += step
